#include "ListComp.h"

#include <iostream>

using namespace std;

/******************************************************************************
 *
 * Définition de la classe ListComp
 *
 *****************************************************************************/

/** Constructeur par défaut.
 * Permet de construire une compétence de classe basique, pouvant
 * éventuellement être associée à un score dépendant du niveau.
 *
 * @param comp nom de la compétence (par défaut "").
 * @param prix coût de la compétence (par défaut 0).
 * @param autre type de la compétence (par défaut Basique).
 */
ListComp::ListComp(const string& comp, const unsigned int& prix,
		   const ScoreAdditionnel& autre)
  : Comp( comp ), AliasComp( comp ), Cout( prix ), Pourcentage( false ),
    ValeurBase( 0 ), AutreScore( autre ), SousCategorie( 0 ), AdresseBase( 0 ),
    aPointeur( false ), choixExclusif( false )
{}

/** Constructeur avec un alias.
 * Permet de construire une compétence de classe basique, dont le nom
 * possède un alias. Est typiquement utilisé pour les sphères et les
 * écoles de magie.
 *
 * @param comp nom de la compétence.
 * @param alias alias de la compétence (càd le nom de fichier /
 * dossier).
 * @param prix coût de la compétence (par défaut 0).
 */
ListComp::ListComp(const string& comp, const string& alias,
		   const unsigned int& prix)
  : Comp( comp ), AliasComp( alias ), Cout( prix ), Pourcentage( false ),
    ValeurBase( 0 ), AutreScore( Normal ), SousCategorie( 0 ), AdresseBase( 0 ),
    aPointeur( false ), choixExclusif( false )
{}

/**
 * Permet de construire une compétence associée à un pourcentage que
 * l'on peut améliorer par la suite. Est utilisé principalement pour
 * les talents de voleur.
 *
 * @param comp nom de la compétence.
 * @param prix coût de la compétence.
 * @param pourcentage booléen activant le pourcentage évolutif (ne
 * sert qu'à faire la distinction entre ce constructeur et le
 * suivant).
 * @param valBase valeur de base du pourcentage.
 */
ListComp::ListComp(const string& comp, const unsigned int& prix,
		   const bool& pourcentage, const unsigned int& valBase)
  : Comp( comp ), AliasComp( comp ), Cout( prix ), Pourcentage( pourcentage ),
    ValeurBase( valBase ), AutreScore( Normal ), SousCategorie( 0 ),
    AdresseBase( 0 ), aPointeur( false ), choixExclusif( false )
{}

/**
 * Permet de construire une compétence "à tiroir", càd la sélection de
 * cette compétence déclenche l'apparition d'un popup qui permet de
 * sélectioner d'autres compétences. Ces compétences ne sont pas à
 * proprement parler des compétences liées à la classe, c'est pourquoi
 * elles sont stockées dans un autre conteneur.
 * 
 * @param comp nom de la compétence.
 * @param prix coût de la compétence.
 * @param base offset appliqué à la compétence pour le stockage dans
 * Classe::Comp_classe (un multiple de 100).
 * @param indice numéro de la liste de compétences "dans le tiroir".
 * @param exclu booléen permettant de choisir entre un choix exclusif
 * ou non (le choix est non-exclusif par défaut).
 */
ListComp::ListComp(const string& comp, const unsigned int& prix,
		   const unsigned int& base, const unsigned int& indice,
		   const bool& exclu)
  : Comp( comp ), AliasComp( comp ), Cout( prix ), Pourcentage( false ),
    ValeurBase( 0 ), AutreScore( Normal ), SousCategorie( indice ),
    AdresseBase( base ), aPointeur( true ), choixExclusif( exclu )
{}

/** Constructeur de copie.
 * Permet de faire une copie profonde d'une instance de ListComp.
 *
 * @param lsComp élément à copier.
 */
ListComp::ListComp(const ListComp& lsComp)
  : Comp( lsComp.Comp ), AliasComp( lsComp.AliasComp ), Cout( lsComp.Cout ),
    Pourcentage( lsComp.Pourcentage ), ValeurBase( lsComp.ValeurBase ),
    AutreScore( lsComp.AutreScore ), SousCategorie( lsComp.SousCategorie ),
    AdresseBase( lsComp.AdresseBase ), aPointeur( lsComp.aPointeur ),
    choixExclusif( lsComp.choixExclusif )
{}

/**
 * Destructeur, ne fait rien de spécial.
 */
ListComp::~ListComp()
{}

/**
 * Permet de faire une affectation propre depuis une autre ListComp.
 *
 * @param lsComp élément à copier.
 * @return référence de l'instance.
 */
ListComp& ListComp::operator=(const ListComp& lsComp)
{
  Comp          = lsComp.Comp;
  AliasComp     = lsComp.AliasComp;
  Cout          = lsComp.Cout;
  Pourcentage   = lsComp.Pourcentage;
  ValeurBase    = lsComp.ValeurBase;
  AutreScore    = lsComp.AutreScore;
  SousCategorie = lsComp.SousCategorie;
  AdresseBase   = lsComp.AdresseBase;
  aPointeur     = lsComp.aPointeur;
  choixExclusif = lsComp.choixExclusif;

  return *this;
}

/**
 * Permet de modifier la valeur de AliasComp une fois l'instance
 * initialisée.
 *
 * @param alias nouvelle valeur de AliasComp.
 */
void ListComp::setAlias(const string& alias)
{
  AliasComp = alias;
}

/**
 * Permet d'afficher simplement une instance de ListComp. On affiche
 * le nom, suivi de l'alias (si existant), le coût et les informations
 * relatives à un éventuel score associé.
 *
 * @param os référence sur le flot de sortie dans lequel seront écrits
 * les champs de l'instance.
 * @param lsComp instance de ListComp que l'on veut écrire.
 *
 * @return une référence sur le flot utilisé.
 */
ostream& operator<<(ostream& os, const ListComp& lsComp)
{
  os << lsComp.Comp;
  if ( lsComp.Comp != lsComp.AliasComp )
    os << " (alias " << lsComp.AliasComp << ")";
  os << ", coût " << lsComp.Cout;
  if ( lsComp.Pourcentage )
    os << " (associé à un pourcentage, valeur de base " << lsComp.ValeurBase
       << ")";
  else if ( lsComp.AutreScore == Basique )
    os << " (associé à un score sur 20 dépendant du niveau)";
  else if ( lsComp.AutreScore == Pourcentage )
    os << " (associé à un pourcentage dépendant du niveau)";
  return os;
}

/**
 * Permet de savoir si la compétence a un pointeur vers une autre
 * liste de compétences, càd si c'est une compétence à tiroir.
 *
 * @return \e true si oui, \e false sinon.
 */
const bool& ListComp::aSousCategorie() const
{
  return aPointeur;
}

/**
 * Permet de savoir si le choix parmi les compétences "à tiroir" est
 * exclusif ou non.
 *
 * @return \e true si oui, \e false sinon.
 */
const bool& ListComp::choixEstExclusif() const
{
  return choixExclusif;
}
